﻿using Kinlo.MESDocking;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using UIWindows.GlobalStatics;
using UIWindows.MESModels;
using UIWindows.Models;
using UIWindows.Models.Devices;
using UIWindows.Models.ParameterModels;
using UIWindows.Services;
using UIWindows.Tools.Helper;
using XingLucifer.Devices;
using XingLucifer.IBase.Enums;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;

namespace UIWindows.Services.PLC_MESHelper
{
    /// <summary>
    /// 设备状态，定时检测
    /// </summary>
    public class DeviceStatusHelper : HelperBase
    {
        PLCBase InjMachine { get; set; }

        MESEquipmentMaintain maintain_Interaction { get; set; }
        MESEquipmentStatus status_Interaction { get; set; }
        public DeviceStatusHelper(
            DeviceInteractiveaddressStatic deviceInteractiveaddressStatic,
            DeviceClientModel deviceModel,
            TemporaryStatic temporaryStatic,
            ParameterStatic parameterStatic,
            DeviceConfigStatic deviceConfigStatic,
            SystemConfigStatic systemConfigStatic,
             HomeStatic homeStatic,
             Action<string, string, string, string, string, long, DateTime, string, string, string, string> log, Action<string, string, string> dialog
            ) : base(deviceInteractiveaddressStatic, deviceModel, temporaryStatic, parameterStatic, deviceConfigStatic, systemConfigStatic, homeStatic, log, dialog)
        {
            InjMachine =  deviceModel.PLC;
            maintain_Interaction = new MESEquipmentMaintain(_log, _dialog, machineInfo_Type);
            status_Interaction = new MESEquipmentStatus(_log, _dialog, machineInfo_Type);
        }
        //public void test()
        //{
        //    //_baseParamete.
        //    _parameter.Class = "666666666666666666666666";
        //    _parameter.UserName = "77777777777777777777";
        //}
        public override Task Handle()
        {
            //await Task.Yield();
            if(machineInfo_Type==MachineInfoTypes.清洗机)
            {
                TaskStatus_Cleaning();
            }else
            {
                TaskStatus_Elapsed();
            }
         
            //Task.CompletedTask 是一个静态属性，表示已完成的 Task。
            return Task.CompletedTask;
        }

        Stopwatch EquipmentMaintain = new Stopwatch();
        /// <summary>
        /// 设备状态
        /// </summary>
        /// <param name="state"></param>
        private void TaskStatus_Elapsed()
        {
            try
            {

                string reason = "";
                string code = "";
                int Alarm = 0;
                int Auto = 0;
                int Stop = 0;
                int Maintain = 0;
                int _recode = 0;
                //_data = Data.MachineList[Convert.ToInt32(index) - 1];

                var addressData = GetAddReassData("AutoAddress");
                //设备状态 0:待机、1:运行、2:故障、3:报警(运行,停止,报警)
                var autoMaintainLst = InjMachine.Read(addressData.PLCAddress, 1);
                //收到空，说明设备不在线
                if (autoMaintainLst == null)
                {
                    return;
                }
                //当前设备状态
                int status = autoMaintainLst[0];

                //待机原因编码
                // _recode = _recodeLst[0];
                //上次设备状态
                int last_status = int.Parse(_parameter.MachineStatus == null ? "0" : _parameter.MachineStatus);
                //当前获取的状态不等于上次状态说明设备切换状态
                if (status != last_status && _parameterStatic.DecideParameter.EnableMES)
                {
                    Dictionary<int, List<MESEquipmentStatusModel>> mesEquipmentStatusData = new Dictionary<int, List<MESEquipmentStatusModel>>();
                    mesEquipmentStatusData.Add(status, new List<MESEquipmentStatusModel>());

                    Dictionary<string, object> mesParam = new Dictionary<string, object>
                    {
                        { "EquipmentCode", _parameter.EquipmentCode==null?"": _parameter.EquipmentCode },
                        { "process_id", _parameter.process_id==null?"": _parameter.process_id },
                    };

                    if (status == 3)
                    {
                        //报警原因编码
                        //var alarmInfosClass = AlarmInfosData.Instance;
                        //var alarmInfosData = alarmInfosClass.GetData();
                        //List<List<PlcAlarmDataModel>> filteredAlarmInfosData = new List<List<PlcAlarmDataModel>>();
                        //if (machineInfo_Type == MachineInfoTypes.装盘机 || machineInfo_Type == MachineInfoTypes.拆盘机)
                        //{
                        //    filteredAlarmInfosData = _temporaryStatic.PLCAlarmList2
                        //    .Where(pair => pair.Key.ToString().Contains($"{_deviceModel.ServiceName}{_deviceModel.Index}"))
                        //   .Select(pair => pair.Value)
                        //     .ToList();
                        //}
                        //else
                        //{
                          
                        //}

                       var filteredAlarmInfosData = _temporaryStatic.PLCAlarmList
                       .Where(pair => _deviceModel.ServiceName.Contains(pair.Key.ToString()) || pair.Key.ToString().Contains(_deviceModel.ServiceName))
                      .Select(pair => pair.Value)
                        .ToList();

                        if (filteredAlarmInfosData.Count > 0)
                        {

                            foreach (var alarmInfo in filteredAlarmInfosData[0])
                            {
                                string deviceType = alarmInfo.DeviceType;
                                string alarmAddress = alarmInfo.AlarmAddress;
                                string alarmContent = alarmInfo.AlarmContent;

                                //是否当前代码报警
                                bool isalarmsta = false;
                                //按位地址取
                                if (alarmInfo.DeviceType.Contains("_Bit"))
                                {
                                    var alarmSta = InjMachine.ReadAndReturnBit(alarmInfo.AlarmAddress);
                                    var condition = alarmSta ? 1 : 0;
                                    if (condition == alarmInfo.Alarmcondition)
                                    {
                                        isalarmsta = true;
                                    }

                                }  //按布尔地址取
                                else
                                {
                                    var alarmSta = InjMachine.Read(alarmInfo.AlarmAddress, 1);
                                    if (alarmSta != null && alarmSta[0] == alarmInfo.Alarmcondition)
                                    {
                                        isalarmsta = true;
                                    }
                                }

                                if (isalarmsta)
                                {
                                    mesEquipmentStatusData[status].Add(new MESEquipmentStatusModel()
                                    {
                                        EquipmentCode = _parameter.EquipmentCode,
                                        State_Code = status.ToString(),
                                        St_seconds = "",
                                        St_ResonCode = "",
                                        Alarm_ResonCode = alarmInfo.Id.ToString(),
                                        Alarm_ResonName = alarmInfo.AlarmContent,

                                        Beg_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                        End_time = "",
                                        //End_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                    });
                                }

                            }
                        }
                        else
                        {
                            code = "001";
                            reason = "报警";
                        }
                    }
                    if (status == 3 && mesEquipmentStatusData[status].Count == 0)
                    {
                        mesEquipmentStatusData[status].Add(
                                            new MESEquipmentStatusModel()
                                            {
                                                EquipmentCode = _parameter.EquipmentCode,
                                                State_Code = status.ToString(),
                                                St_seconds = "",
                                                St_ResonCode = "",
                                                Alarm_ResonCode = "999",
                                                Alarm_ResonName = "报警",
                                                Beg_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                                End_time = "",
                                                //End_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                            }
                                        );
                    }
                    //故障报修调用接口
                    if (status == 2)
                    {
                        var mesParameters = new Dictionary<string, object>()
                        {
                            {"EquipmentCode", _parameter.EquipmentCode },     //设备编码
                            {"UserName",_parameter.UserName },             //登录账号
                            {"Type","0" },
                        };


                        mesParam.Add("parameter", mesParameters);

                        

                        if (EquipmentMaintain.IsRunning&& EquipmentMaintain.Elapsed.TotalMinutes < 10)
                        {
                            return;
                        }else if(!EquipmentMaintain.IsRunning)
                        {
                            EquipmentMaintain.Start();
                        }
                        else
                        {
                            EquipmentMaintain.Restart();
                        }


                      var result = maintain_Interaction.MESInteraction(_parameterStatic.MESParameter.EquipmentMaintainRouter,
                             _parameterStatic.MESParameter.EquipmentMaintainTime,
                             1, DateTime.Now, mesParam);

                        if (result == ResultTypes.合格)
                        {
                            _parameter.MachineStatus = status.ToString();
                            //Data.MachineList[Convert.ToInt32(index) - 1] = _data;
                        }
                        return;
                    }

                    if (status == 1 || status == 0)
                    {
                        mesEquipmentStatusData[status].Add(
                            new MESEquipmentStatusModel()
                            {
                                EquipmentCode = _parameter.EquipmentCode,
                                State_Code = status.ToString(),
                                St_ResonCode = "",
                                St_seconds = "",
                                Alarm_ResonCode = "",
                                Alarm_ResonName = "",
                                Beg_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                End_time = "",
                            }
                         );
                    }
                    //待机时间
                    int secondsDifference = 0;
                    //切换状态传当前的状态信息给MES
                    if (_parameter.last_StatusData.TryGetValue(_parameter.last_StatusData.Keys.FirstOrDefault(), out List<MESEquipmentStatusModel> firstList))
                    {
                        //上次状态是否待机
                        bool isLast_Status = _parameterStatic.MESCollectionItemsParameter.ContainsKey(0);

                        if (isLast_Status)
                        {
                            addressData = GetAddReassData("StopReasonAddress");
                            //待机原因编码
                            var _recodeLst = InjMachine.Read(addressData.PLCAddress, 1);
                            //判断是否选了待机原因，选了就更新上一次的待机原因
                            if (_recodeLst != null && _recodeLst[0] != 0)
                            {
                                for (int i = 0, j = 1; i <= 10; i++)
                                {
                                    if (_recodeLst[0] == j)
                                    {
                                        _recode = i;
                                    }
                                    j = j * 2;
                                }
                                //addressData = GetAddReassData("StopReasonAddress");
                                //保存待机原因编码
                                _parameter.last_recode = _recode;
                                InjMachine.Write(addressData.PLCAddress, new short[] { 0 });
                            }
                            else
                            {
                                _parameter.last_recode = 0;
                            }
                        }

                        DateTime begTime;

                        //结束时间减去开始时间算出秒
                        DateTime dateTime1 = DateTime.TryParse(firstList[0].Beg_time, out begTime) ? begTime : DateTime.Now; ;
                        DateTime dateTime2 = DateTime.Now;
                        TimeSpan timeDifference = dateTime2 - dateTime1;
                        secondsDifference = (int)timeDifference.TotalSeconds;
                        firstList.ForEach(x =>
                        {
                            x.End_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                            x.St_seconds = secondsDifference.ToString();
                            x.St_ResonCode = isLast_Status ? _parameter.last_recode.ToString() : "";
                        });

                        firstList.AddRange(mesEquipmentStatusData[status]);

                        mesParam.Remove("parameter");

                        mesParam.Add("parameter", new Dictionary<string, object>() { { "data", firstList } });

                        var result = status_Interaction.MESInteraction(_parameterStatic.MESParameter.EquipmentStatusRoute,
                        _parameterStatic.MESParameter.EquipmentStatusTime,
                        1, DateTime.Now, mesParam);

                        if (result != ResultTypes.合格)
                        {
                            //Messenger.Default.Send(firstList, "EquipmentStatus");
                        }
                    }

                    //清空上次状态
                    _parameter.last_StatusData.Clear();
                    //保存当前状态，留下次用
                    _parameter.last_StatusData.Add(status, new List<MESEquipmentStatusModel>(mesEquipmentStatusData[status]));
                    _parameter.MachineStatus = status.ToString();
                    //Data.MachineList[Convert.ToInt32(index) - 1] = _data;
                }
                else
                {
                    _parameter.MachineStatus = status.ToString();
                    
                }
                _temporaryStatic.mesCollectionItemsTemporary[(int)machineInfo_Type].MachineStatus = status.ToString();
            }
            catch (Exception ex)
            {
                RunLog($"【设备状态定时任务异常:{ex.ToString()}");
                return;
            }
        }

        /// <summary>
        /// 清洗机设备状态
        /// </summary>
        /// <param name="state"></param>
        private void TaskStatus_Cleaning()
        {
            //Task.Run(() =>
            //{
            try
            {
                string reason = "";
                string code = "";
                int Alarm = 0;
                int Auto = 0;
                int Stop = 0;
                int Maintain = 0;
                int _recode = 0;
                //_data = Data.MachineList[Convert.ToInt32(index) - 1];

                var addressData = GetAddReassData("AutoAddress");
                //设备状态 0:待机、1:运行、2:故障、3:报警(运行,停止,报警)
                var autoMaintainLst = InjMachine.Read(addressData.PLCAddress, 1);
                //收到空，说明设备不在线
                if (autoMaintainLst == null)
                {
                    // _data.MachineStatus = "6";
                    //lock (lockSaveObject)
                    //{
                    //    Data.MachineList[Convert.ToInt32(index) - 1] = _data;
                    //}
                    //Data.MachineList[Convert.ToInt32(index) - 1] = _data;
                    return;
                }
                //当前设备状态
                int status = autoMaintainLst[0];

                int last_status = int.Parse(_parameter.MachineStatus == null ? "0" : _parameter.MachineStatus);
                //当前获取的状态不等于上次状态说明设备切换状态
                if (status != last_status && _parameterStatic.DecideParameter.EnableMES)
                {
                    Dictionary<int, List<MESEquipmentStatusModel>> mesEquipmentStatusData = new Dictionary<int, List<MESEquipmentStatusModel>>();
                    mesEquipmentStatusData.Add(status, new List<MESEquipmentStatusModel>());

                    Dictionary<string, object> mesParam = new Dictionary<string, object>
                    {
                        { "EquipmentCode", _parameter.EquipmentCode==null?"": _parameter.EquipmentCode },
                        { "process_id", _parameter.process_id==null?"": _parameter.process_id },
                    };
                    //保存切换到待机状态的当前时间
                    //if (status == 0)
                    //{
                    //    last_StSeconds = DateTime.Now;
                    //}
                    if (status == 3)
                    {

                        var filteredAlarmInfosData = _temporaryStatic.PLCAlarmList
                                  .Where(pair => _deviceModel.ServiceName.Contains(pair.Key.ToString()) || pair.Key.ToString().Contains(_deviceModel.ServiceName))
                                 .Select(pair => pair.Value)
                                   .ToList();
                        if (filteredAlarmInfosData.Count > 0)
                        {
                            foreach (var alarmInfo in filteredAlarmInfosData[0])
                            {
                                string deviceType = alarmInfo.DeviceType;
                                string alarmAddress = alarmInfo.AlarmAddress;
                                string alarmContent = alarmInfo.AlarmContent;
                                int alarmcondition = alarmInfo.Alarmcondition;
                                var address = alarmAddress;

                                var result = InjMachine.ReadBool(address);
                                var determine = alarmcondition == 1 ? true : false;
                                if (result == determine)
                                {
                                    mesEquipmentStatusData[status].Add(new MESEquipmentStatusModel()
                                    {
                                        EquipmentCode = _parameter.EquipmentCode,
                                        State_Code = status.ToString(),
                                        St_seconds = "",
                                        St_ResonCode = "",
                                        Alarm_ResonCode = alarmInfo.Id.ToString(),
                                        Alarm_ResonName = alarmInfo.AlarmContent,

                                        Beg_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                        End_time = "",
                                        //End_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                    });
                                }
                            }
                        }
                        else
                        {
                            code = "001";
                            reason = "报警";
                        }
                    }
                    if (status == 3 && mesEquipmentStatusData[status].Count == 0)
                    {
                        mesEquipmentStatusData[status].Add(
                                            new MESEquipmentStatusModel()
                                            {
                                                EquipmentCode = _parameter.EquipmentCode,
                                                State_Code = status.ToString(),
                                                St_seconds = "",
                                                St_ResonCode = "",
                                                Alarm_ResonCode = "999",
                                                Alarm_ResonName = "报警",
                                                Beg_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                                End_time = "",
                                                //End_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                            }
                                        );
                    }
                    //故障报修调用接口
                    if (status == 2)
                    {
                        var mesParameters = new Dictionary<string, object>()
                        {
                            {"EquipmentCode", _parameter.EquipmentCode },     //设备编码
                            {"UserName",_parameter.UserName },             //登录账号
                            {"Type","0" },
                        };


                        mesParam.Add("parameter", mesParameters);



                        if (EquipmentMaintain.IsRunning && EquipmentMaintain.Elapsed.TotalMinutes < 10)
                        {
                            return;
                        }
                        else if (!EquipmentMaintain.IsRunning)
                        {
                            EquipmentMaintain.Start();
                        }
                        else
                        {
                            EquipmentMaintain.Restart();
                        }


                        var result = maintain_Interaction.MESInteraction(_parameterStatic.MESParameter.EquipmentMaintainRouter,
                               _parameterStatic.MESParameter.EquipmentMaintainTime,
                               1, DateTime.Now, mesParam);

                        if (result == ResultTypes.合格)
                        {
                            _parameter.MachineStatus = status.ToString();
                            //Data.MachineList[Convert.ToInt32(index) - 1] = _data;
                        }
                        return;
                    }

                    if (status == 1 || status == 0)
                    {
                        mesEquipmentStatusData[status].Add(
                            new MESEquipmentStatusModel()
                            {
                                EquipmentCode = _parameter.EquipmentCode,
                                State_Code = status.ToString(),
                                St_ResonCode = "",
                                St_seconds = "",
                                Alarm_ResonCode = "",
                                Alarm_ResonName = "",
                                Beg_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                                End_time = "",
                            }
                         );
                    }
                    //待机时间
                    int secondsDifference = 0;
                    //切换状态传当前的状态信息给MES
                    if (_parameter.last_StatusData.TryGetValue(_parameter.last_StatusData.Keys.FirstOrDefault(), out List<MESEquipmentStatusModel> firstList))
                    {
                        //上次状态是否待机
                        bool isLast_Status = _parameterStatic.MESCollectionItemsParameter.ContainsKey(0);

                        if (isLast_Status)
                        {
                            addressData = GetAddReassData("StopReasonAddress");
                            //待机原因编码
                            var _recodeLst = InjMachine.Read(addressData.PLCAddress, 1);
                            //判断是否选了待机原因，选了就更新上一次的待机原因
                            if (_recodeLst != null && _recodeLst[0] != 0)
                            {
                                for (int i = 0, j = 1; i <= 10; i++)
                                {
                                    if (_recodeLst[0] == j)
                                    {
                                        _recode = i;
                                    }
                                    j = j * 2;
                                }
                                //addressData = GetAddReassData("StopReasonAddress");
                                //保存待机原因编码
                                _parameter.last_recode = _recode;
                                InjMachine.Write(addressData.PLCAddress, new short[] { 0 });
                            }
                            else
                            {
                                _parameter.last_recode = 0;
                            }
                        }

                        DateTime begTime;

                        //结束时间减去开始时间算出秒
                        DateTime dateTime1 = DateTime.TryParse(firstList[0].Beg_time, out begTime) ? begTime : DateTime.Now; ;
                        DateTime dateTime2 = DateTime.Now;
                        TimeSpan timeDifference = dateTime2 - dateTime1;
                        secondsDifference = (int)timeDifference.TotalSeconds;
                        firstList.ForEach(x =>
                        {
                            x.End_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                            x.St_seconds = secondsDifference.ToString();
                            x.St_ResonCode = isLast_Status ? _parameter.last_recode.ToString() : "";
                        });

                        firstList.AddRange(mesEquipmentStatusData[status]);

                        mesParam.Remove("parameter");

                        mesParam.Add("parameter", new Dictionary<string, object>() { { "data", firstList } });

                        var result = status_Interaction.MESInteraction(_parameterStatic.MESParameter.EquipmentStatusRoute,
                        _parameterStatic.MESParameter.EquipmentStatusTime,
                        1, DateTime.Now, mesParam);

                        if (result != ResultTypes.合格)
                        {
                            //Messenger.Default.Send(firstList, "EquipmentStatus");
                        }
                    }

                    //清空上次状态
                    _parameter.last_StatusData.Clear();
                    //保存当前状态，留下次用
                    _parameter.last_StatusData.Add(status, new List<MESEquipmentStatusModel>(mesEquipmentStatusData[status]));
                    _parameter.MachineStatus = status.ToString();
                }
                else
                {
                    _parameter.MachineStatus = status.ToString();

                }
                _temporaryStatic.mesCollectionItemsTemporary[(int)machineInfo_Type].MachineStatus = status.ToString();


            }
            catch (Exception ex)
            {
                RunLog($"【设备状态定时任务异常:{ex.ToString()}");
                return;
            }

            //});
        }

    }
}
